package com.cictec.middleware.gps.engine.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.cictec.middleware.commons.utils.Constants;
import com.cictec.middleware.commons.utils.DateUtils;
import com.cictec.middleware.commons.utils.PropertiesUtils;
import com.cictec.middleware.gps.engine.BusInstance;
import com.cictec.middleware.gps.engine.TimingPoint;
import com.cictec.middleware.gps.engine.caculate.entity.BusEngine;
import com.cictec.middleware.gps.engine.caculate.entity.BusTrip;

/**
 * 位置信息，存储、发送处理
 * @author Administrator
 *
 */
@SuppressWarnings({"unchecked", "rawtypes"})
@Component
public class DataStorageToRedisService {

	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	
	/**
	 * 获取redis中指定日期的原始位置信息keys
	 * 
	 * @param date
	 * @return
	 */
	public List<String> getPositionTMKeysFromRedis(String date){

		List<String> list = new ArrayList<String>();
		
		Set<String> keys = stringRedisTemplate.keys("*-TM");
		
		String datestr = date.replaceAll("-", "");
		for (String redisKey : keys) {
			String[] keySplit = redisKey.split("-");
			if(keySplit[0].equals(datestr)){
				list.add(redisKey);
			}
		}
		
		return list;
	}
	
	
	/**
	 * 保存位置数据到 【原始数据】
	 * <br>【rediskey  -->  yyyyMMdd-车牌号-TM】
	 * @param devCode
	 * @param timingPoint
	 */
	public void savePositionTMRedis(String devCode, TimingPoint timingPoint) {

		String date = DateUtils.formatDate(timingPoint.getTime(), "yyyyMMdd");
		String redisKey = date + "-" + devCode + "-TM";

		stringRedisTemplate.opsForZSet().add(redisKey, JSON.toJSONString(timingPoint), timingPoint.getTime().getTime());
		// 设置过期时间，默认48小时
		int expireSecond = PropertiesUtils.getIntValue("redis.busPositionTM.expire", 60*60*24*2);
		stringRedisTemplate.expire(redisKey, expireSecond, TimeUnit.SECONDS);

	}
	
	/**
	 * 获取车辆指定日期 原始位置信息
	 * <br>按照线路分组
	 * @param date
	 * @param devCode
	 * @param isCalculateMilage
	 * @return
	 */
	public List<TimingPoint> getPositionTMFromRedis(String date, String devCode, boolean isCalculateMilage){
		
		String redisKey = date.replace("-", "") + "-" + devCode + "-TM";
		long endTime = DateUtils.getEndDateTime(date).getTime();
		
		List<TimingPoint> rtList = new ArrayList<TimingPoint>();
		
		Set<String> results = stringRedisTemplate.opsForZSet().rangeByScore(redisKey, 0, endTime);
		Iterator it = results.iterator();
		while (it.hasNext()) {
			String str = it.next().toString();
			TimingPoint timingObject = JSON.parseObject(str, TimingPoint.class);
			if(isCalculateMilage){
				timingObject.setAttribute(Constants.CALCULATE_MILEAGE, Constants.CALCULATE_MILEAGE);
			}
			rtList.add(timingObject);
		}
		return rtList;
	}
	
	
	/**
	 * 保存位置信息【处理后的】【过期时间 默认24小时】
	 * <p> 【rediskey  -->  yyyyMMdd-车牌号】
	 * @param busInstance
	 */
	public void saveBusInstanceToRedis(BusInstance busInstance) {
		
		String currentDate = DateUtils.formatDate(busInstance.getTime());
		
		String redisKey = currentDate.replace("-", "") + "-" + busInstance.getBusNumber();
		stringRedisTemplate.opsForZSet().add(redisKey, JSON.toJSONString(busInstance.getAttributes()), busInstance.getTime().getTime());
		
		// 设置过期时间，默认24小时
		int expireSecond = PropertiesUtils.getIntValue("redis.busPosition.expire", 60*60*24*1);
		stringRedisTemplate.expire(redisKey, expireSecond, TimeUnit.SECONDS);
	}
	
	/**
	 * 获取位置信息【处理后的】
	 * <br>【rediskey  -->  yyyyMMdd-车牌号】
	 * @param busNumber
	 * @param startTime   
	 * @param endTime
	 * @return
	 */
	public List<TimingPoint> getPositionFromRedis(String busNumber, Date startTime, Date endTime){
		
		List<TimingPoint> timingPointList = new ArrayList<TimingPoint>();
		// 处理后的位置信息
		String redisKey = DateUtils.formatDate(startTime, "yyyyMMdd").replace("-", "") + "-" + busNumber;
		
		if (stringRedisTemplate.hasKey(redisKey)) {
			Set<String> results = stringRedisTemplate.opsForZSet().rangeByScore(redisKey, startTime.getTime(), endTime.getTime());
			Iterator it = results.iterator();
			while (it.hasNext()) {
				String str = it.next().toString();
				TimingPoint model = JSON.parseObject(str, TimingPoint.class);
				timingPointList.add(model);
			}
		}
		
		return timingPointList;
		
	}
	
	/**
	 * 判断如果是 进出站信息（含有 dataTypeTME 标识）
	 * <br>【用于里程统计、趟次计算】
	 * <br>【过期时间默认24】
	 * <br>【redisKey --> yyyyMMdd-车牌号-enter】
	 * @param busInstance
	 */
	public void saveEnterOutToRedis(BusInstance busInstance){
		if(!busInstance.isEnterOut()){
			return;
		}
		
		// 判断为设备上报的进出站数据
		if (!busInstance.isBusMileageCaculate()) {
			
			String currentDate = DateUtils.formatDate(busInstance.getTime());
			// redis 存储进出站信息key---> yyyymmdd-plateNumber-enter
			String redisKey = currentDate.replace("-", "") + "-" + busInstance.getBusNumber() + "-enter";
			
			TimingPoint point = new TimingPoint();
			point.setTime(busInstance.getTime());
			point.setAttributes(busInstance.getAttributes());
			
			stringRedisTemplate.opsForZSet().add(redisKey, JSON.toJSONString(point), busInstance.getTime().getTime());
			
			// 设置过期时间，默认24小时
			int expireSecond = PropertiesUtils.getIntValue("redis.busEnterOut.expire", 60*60*24*1);
			stringRedisTemplate.expire(redisKey, expireSecond, TimeUnit.SECONDS);
		}
	}
	
	/**
	 * 获取进出站数据
	 * <br> redisKey ---> 【yyyyMMdd-车牌号-enter】
	 * @param busNumber 车牌号
	 * @param startDate 开始时间
	 * @param endDate   结束时间
	 * @return
	 */
	public List<TimingPoint> getEnterOutFromRedis(String busNumber, Date startDate, Date endDate){
		
		
		List<TimingPoint> timingList = new ArrayList<TimingPoint>();
		
		String date = DateUtils.formatDate(startDate, "yyyyMMdd");
		
		ZSetOperations ops = stringRedisTemplate.opsForZSet();
		String redisName = date + "-" + busNumber + "-enter";
		if(stringRedisTemplate.hasKey(redisName)){
			Set<String> results = ops.rangeByScore(redisName, startDate.getTime(), endDate.getTime());
			Iterator it = results.iterator();
			while (it.hasNext()) {
				String str = it.next().toString();
				TimingPoint model = JSON.parseObject(str, TimingPoint.class);
				timingList.add(model);
			}
			
			return timingList;
		}
		
		return timingList;
	}
	
	/**
	 * 保存车辆【实时趟次】数据
	 * <br>【rediskey  -->  车牌号】
	 * @param busNumber
	 * @param busTripTemp
	 */
	public void saveBusTripToRedis(String busNumber, BusTrip busTripTemp){
		stringRedisTemplate.opsForHash().put(busNumber, DateUtils.formatDateTimes(busTripTemp.getStartTime()), JSON.toJSONString(busTripTemp));
	}
	
	/**
	 * 保存里程统计数据【redis】
	 * <br>【redisKey --> busMileages】
	 * @param date
	 * @param busNumber
	 * @param busEngile
	 */
	public void saveBusMileageToRedis(String date, BusEngine busEngile){
		
		String redisKey = "busMileages";
//		String field = busEngile.getLinename() + "-" + busNumber + "-" + date;
		String fieldKey = date.replaceAll("-", "") + "-" + busEngile.getLinename() + "-" + busEngile.getPlate();
		
		String cdate = DateUtils.formatDate(DateUtils.getDateFromDate(new Date(), -1));
		stringRedisTemplate.opsForHash().put(redisKey, fieldKey, JSON.toJSONString(busEngile));
		if(!cdate.equals(date)){
			String redisKey1 = "busMileages_supply";
			stringRedisTemplate.opsForHash().put(redisKey1, fieldKey, JSON.toJSONString(busEngile));
		}
	}
	
	/**
	 * 保存离线车辆在线的最后一个点的位置信息
	 */
	public void saveBusOfflinePositation(BusInstance busInstance){
		String redisKey = "busOfflinePosition";
		String fieldKey = busInstance.getBusUuid();
		String fieldValue = JSON.toJSONString(busInstance.getAttributes());
		
		stringRedisTemplate.opsForHash().put(redisKey, fieldKey, fieldValue);
	}
	/**
	 * 保存离线车辆在线的最后一个点的位置信息
	 */
	public void deleteBusOfflinePositation(BusInstance busInstance){
		String redisKey = "busOfflinePosition";
		String fieldKey = busInstance.getBusUuid();
		
		HashOperations ops = stringRedisTemplate.opsForHash();
		if(ops.hasKey(redisKey, fieldKey)){
			ops.delete(redisKey, fieldKey);
		}
	}
}
